Proto3 简介

Proto3 简介。

简单例子

proto文件

1
2
3
4
5
6
syntax = "proto3"
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}

第一行表示使用proto3语法,没有的话默认为proto2
SearchRequest是一个查询请求的数据格式。
查询语句query,查询页码page_number,每页结果数result_per_page
每个字段都是一个键值对的形式。每个字段都有一个类型。
但是后面的1 2 3并不是这些字段的值。而是这些字段的tag,每个字段都有一个唯一的数字tag,这些tag用来在数据的二进制格式中来表示这些字段,可用范围是1-2^29-1,其中19000-19999不能用。
1-15的字段在二进制格式中会使用1个字节来编码,16-2047的字段用两个字节。

字段可用修饰符

repeated 使用这个修饰的字段在生成的Java类中该字段是个列表。

proto2 中的required,optionalproto3已不使用。

Scalar Type

可以使用的字段类型有:float,double,int32,int64,uint32,uint64,sint32,sint64,fixed32,fixed64,sfixed32,sfixed64,bool,string,bytes。

所有的带有32的类型在Java中转换成int,所有带有64的类型转换成long,bytes转换成ByteString,其他类型转成对应的Java中的类型。

其他语言的转换见Scalar Type

类型默认值

字段如果没有指定值,则会使用默认值。
数值类型为0
string为空字符串””
bytes为空bytes
bool为false
enums为enums中第一个值(0)
其他为null

枚举类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
Corpus corpus = 4;
}

枚举的第一个值必须是0。

自定义Message类型

1
2
3
4
5
6
7
8
9
message SearchResponse {
repeated Result result = 1;
}

message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
}

导入

import "myproject/other_protos.proto";

嵌套

1
2
3
4
5
6
7
8
message SearchResponse {
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
}
repeated Result result = 1;
}

如果想在外面使用Result类型

1
2
3
message SomeOtherMessage {
SearchResponse.Result result = 1;
}

Map

map<key_type, value_type> map_field = N;

key_type可以是任意的Scalar类型(除了浮点类型和bytes)
value_type可以是任意类型。
map不能使用repeated。

定义Service

1
2
3
service SearchService {
rpc Search (SearchRequest) returns (SearchResponse);
}

options

所有的options在google/protobuf/descriptor.proto中。

常用options

java_package:
option java_package = "com.example.foo";
表示生成的Java类的包名。

java_outer_classname:
option java_outer_classname = "Ponycopter";
表示生成的Java类的类名。

编译生成Java类

1
protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR path/to/file.proto